package br.com.sistransporte.transite.trajeto.dao;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;

import org.hibernate.Query;
import org.hibernate.Session;

import br.com.sistransporte.transitevo.linha.model.LinhaVO;
import br.com.sistransporte.transitevo.trajeto.model.TrajetoVO;
import br.com.src.masterpersistence.dao.GenericDAO;
import br.com.src.masterpersistence.exceptions.AlterarException;
import br.com.src.masterpersistence.exceptions.ExcluirException;
import br.com.src.masterpersistence.exceptions.FiltrarException;
import br.com.src.masterpersistence.exceptions.HibernatePersistenceException;
import br.com.src.masterpersistence.exceptions.InserirException;
import br.com.src.masterpersistence.utilidades.FabricaMensagensLog;
import br.com.src.masterpersistence.utilidades.Paginacao;
import br.com.src.utilidades.exceptions.DesconhecidoException;

public class TrajetoDAOImpl extends GenericDAO<TrajetoVO> implements TrajetoDAOService {

	public TrajetoDAOImpl(String typeSessionFactory) {
		super(typeSessionFactory);
		logger.info( FabricaMensagensLog.getMensagemLogConstrutor("TrajetoDAOImpl") );
	}

	
	public ArrayList<TrajetoVO> filtrar(TrajetoVO vo, boolean isDisticnt,boolean isLike) throws FiltrarException {
		logger.info( FabricaMensagensLog.getMensagemLogInicio("TrajetoDAOImpl") );
		try {
			ArrayList< TrajetoVO > lista = filter( vo, isDisticnt, isLike );
			logger.info( FabricaMensagensLog.getMensagemLogTermino( "TrajetoDAOImpl" ) );
			return lista;
		} catch ( IllegalArgumentException e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro("TrajetoDAOImpl", e ) );
			throw new FiltrarException( e.getMessage(), e );
		} catch ( IllegalAccessException e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro( "TrajetoDAOImpl", e ) );
			throw new FiltrarException( e.getMessage(), e );
		} catch ( InvocationTargetException e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro( "TrajetoDAOImpl", e ) );
			throw new FiltrarException( e.getMessage(), e );
		} catch ( Exception e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro( "TrajetoDAOImpl", new DesconhecidoException( e.getMessage(), e ) ) );
			throw new FiltrarException( e.getMessage(), e );
		}
	}
	
	public TrajetoVO inserir(TrajetoVO vo) throws InserirException {
		try {
			logger.info( FabricaMensagensLog.getMensagemLogInicio( "TrajetoDAOImpl" ) );
			TrajetoVO objetoPersistido = (TrajetoVO) insert( vo );
			logger.info( FabricaMensagensLog.getMensagemLogTermino( "TrajetoDAOImpl" ) );
			return objetoPersistido;
		} catch ( HibernatePersistenceException e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro( "TrajetoDAOImpl", e ) );
			throw new InserirException( e.getMessage(), e );
		}
	}

	
	public void alterar(TrajetoVO vo) throws AlterarException {
		logger.info( FabricaMensagensLog.getMensagemLogInicio( "TrajetoDAOImpl" ) );
		try {
			update( vo );
		} catch ( HibernatePersistenceException e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro("TrajetoDAOImpl", e ) );
			throw new AlterarException( e.getMessage(), e );
		}
		logger.info( FabricaMensagensLog.getMensagemLogTermino("TrajetoDAOImpl" ) );
	    
		
	}

	
	public void excluir(TrajetoVO vo) throws ExcluirException {
		logger.info( FabricaMensagensLog.getMensagemLogInicio( "TrajetoDAOImpl" ) );
		try {
			delete( vo );
		} catch ( HibernatePersistenceException e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro( "TrajetoDAOImpl", e ) );
			throw new ExcluirException( e.getMessage(), e );
		}
		logger.info( FabricaMensagensLog.getMensagemLogTermino( "TrajetoDAOImpl" ) );
	}

	
	public ArrayList<TrajetoVO> filtrarPaginacao(Paginacao<TrajetoVO> pagination, TrajetoVO vo, boolean isDisticnt,	boolean isLike) throws FiltrarException {
		logger.info( FabricaMensagensLog.getMensagemLogInicio( "TrajetoDAOImpl" ) );
		try {
			ArrayList< TrajetoVO > lista = paginacao( pagination, vo, isDisticnt, isLike );
			logger.info( FabricaMensagensLog.getMensagemLogTermino( "TrajetoDAOImpl" ) );
			return lista;
		} catch ( IllegalArgumentException e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro( "TrajetoDAOImpl", e ) );
			throw new FiltrarException( e.getMessage(), e );
		} catch ( IllegalAccessException e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro( "TrajetoDAOImpl", e ) );
			throw new FiltrarException( e.getMessage(), e );
		} catch ( InvocationTargetException e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro( "TrajetoDAOImpl", e ) );
			throw new FiltrarException( e.getMessage(), e );
		} catch ( Exception e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro( "TrajetoDAOImpl", new DesconhecidoException( e.getMessage(), e ) ) );
			throw new FiltrarException( e.getMessage(), e );
		}
		
	}
	
	@Override
    public Integer getTotalCadastrados( TrajetoVO entidade, boolean isDisticnt, boolean isLike ) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
		return super.getTotalCadastrados( entidade, isDisticnt, isLike );
    }
	
	@SuppressWarnings( "unchecked" )
    public ArrayList<TrajetoVO> listarTrajetosPorLinha(LinhaVO vo) throws FiltrarException {
		logger.info( FabricaMensagensLog.getMensagemLogInicio("TrajetoDAOImpl") );
		Session session = getSessaoAberta();
		try {
			
			Query query = session.createQuery("SELECT t FROM TrajetoVO t "+
											"WHERE t.linha.id = :codigo)");
			query.setInteger("codigo", vo.getId());
			
			ArrayList< TrajetoVO > listaTrajetos = (ArrayList< TrajetoVO >) query.list();
			
			return listaTrajetos;
		} catch ( IllegalArgumentException e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro("TrajetoDAOImpl", e ) );
			throw new FiltrarException( e.getMessage(), e );
		} catch ( Exception e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro( "TrajetoDAOImpl", new DesconhecidoException( e.getMessage(), e ) ) );
			throw new FiltrarException( e.getMessage(), e );
		}finally {
			session.close();
		}
	}
}
